﻿#ifndef __STD_FILESYSTEM_H__
#define __STD_FILESYSTEM_H__

#if _HAS_CXX17
#include <filesystem>
#else
#include <algorithm>
#include <string>
namespace std
{
    namespace filesystem
    {
        class path
        {
        public:
            path(const std::string &path) : m_path(path) {}

            const std::string &string() { return m_path; }
            bool empty() { return m_path.empty(); }
            operator std::string() { return m_path; }

            path filename() const
            {
                auto pos = m_path.find_last_of("/\\");
                return pos == std::string::npos ? m_path : path(m_path.substr(pos + 1));
            }

            path replace_extension(const std::string &ext)
            {
                return path(m_path.substr(0, m_path.find_last_of(".")) + ext);
            }

            path replace_extension(const path &ext)
            {
                return replace_extension(ext.m_path);
            }

            path extension()
            {
                return path(m_path.substr(m_path.find_last_of(".")));
            }

            path operator=(const std::string &_path)
            {
                m_path = _path;
                return *this;
            }

            path operator/(const std::string &other)
            {
                return path(format_path(m_path + "/" + other));
            }

            path operator/(const path &other)
            {
                return path(format_path(m_path + "/" + other.m_path));
            }

            path parent_path()
            {
                auto pos = m_path.find_last_of("/\\");
                return pos == std::string::npos ? path("") : path(m_path.substr(0, pos));
            }

        protected:
            std::string format_path(const std::string &path)
            {
                std::string fmt_path = path;
                std::replace(fmt_path.begin(), fmt_path.end(), '\\', '/');
                // clang-format off
                auto newEnd = std::unique(fmt_path.begin(), fmt_path.end(), [](char a, char b) { return a == '/' && b == '/'; });
                // clang-format on
                fmt_path.erase(newEnd, fmt_path.end());
                return fmt_path;
            }

        protected:
            std::string m_path;
        };

        static bool exists(const path &_path) { return false; }
        static bool exists(const std::string &_path) { return false; }
        static void create_directories(const path &_path) {}
        static void create_directories(const std::string &_path) {}
    }
}
#endif

#endif
